package com.space.mygql.stitching.namespace.nacos;

import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.SystemPropertyKeyConst;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.client.config.http.HttpAgent;
import com.alibaba.nacos.client.config.http.MetricsHttpAgent;
import com.alibaba.nacos.client.config.http.ServerHttpAgent;
import com.alibaba.nacos.client.utils.LogUtils;
import com.alibaba.nacos.client.utils.TemplateUtils;
import com.alibaba.nacos.client.utils.TenantUtil;
import com.alibaba.nacos.common.http.HttpRestResult;
import com.space.mygql.stitching.namespace.NameSpaceService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @author <a href="mailto:414563035@qq.com">Bedroom</a>
 * @date 2021/5/26 6:49 下午
 */
public class NacosNameSpaceService implements NameSpaceService {
    public static final String CONFIG_CONTROLLER_PATH = "/v1/console/namespaces";

    private static final Logger LOGGER = LogUtils.logger(NacosNameSpaceService.class);
    private static final long POST_TIMEOUT = 3000L;
    /**
     * http agent
     */
    private final HttpAgent agent;
    private final String encode;

    public NacosNameSpaceService(Properties properties) throws NacosException {
        String encodeTmp = properties.getProperty(PropertyKeyConst.ENCODE);
        if (StringUtils.isBlank(encodeTmp)) {
            encode = Constants.ENCODE;
        } else {
            encode = encodeTmp.trim();
        }
        initNamespace(properties);
        agent = new MetricsHttpAgent(new ServerHttpAgent(properties));
        agent.start();
    }

    private void initNamespace(Properties properties) {
        String namespace = parseNamespace(properties);
        properties.put(PropertyKeyConst.NAMESPACE, namespace);
    }

    /**
     * 发布namespace
     *
     * @param namespaceId
     * @param namespaceName
     * @param namespaceDesc
     * @return
     */
    @Override
    public boolean publishNameSpace(String namespaceId, String namespaceName, String namespaceDesc) {
        return publishNameSpaceInner(namespaceId, namespaceName, namespaceDesc);
    }

    private boolean publishNameSpaceInner(String namespaceId, String namespaceName, String namespaceDesc) {
        Map<String, String> params = new HashMap<>(4);
        params.put("customNamespaceId", namespaceId);
        params.put("namespaceName", namespaceName);
        params.put("namespaceDesc", namespaceDesc);

        Map<String, String> headers = new HashMap<>(2);

        try {
            HttpRestResult<String> result = agent.httpPost(CONFIG_CONTROLLER_PATH, headers, params, encode, POST_TIMEOUT);
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            return false;
        }
        return true;
    }

    public static String parseNamespace(Properties properties) {
        String namespaceTmp = null;

        String isUseCloudNamespaceParsing =
                properties.getProperty(PropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
                        System.getProperty(SystemPropertyKeyConst.IS_USE_CLOUD_NAMESPACE_PARSING,
                                String.valueOf(Constants.DEFAULT_USE_CLOUD_NAMESPACE_PARSING)));

        if (Boolean.parseBoolean(isUseCloudNamespaceParsing)) {
            namespaceTmp = TemplateUtils.stringBlankAndThenExecute(namespaceTmp, TenantUtil::getUserTenantForAcm);

            namespaceTmp = TemplateUtils.stringBlankAndThenExecute(namespaceTmp, () -> {
                String namespace = System.getenv(PropertyKeyConst.SystemEnv.ALIBABA_ALIWARE_NAMESPACE);
                return StringUtils.isNotBlank(namespace) ? namespace : StringUtils.EMPTY;
            });
        }

        if (StringUtils.isBlank(namespaceTmp)) {
            namespaceTmp = properties.getProperty(PropertyKeyConst.NAMESPACE);
        }
        return StringUtils.isNotBlank(namespaceTmp) ? namespaceTmp.trim() : StringUtils.EMPTY;
    }
}